package com.mycompany.myapp.web.rest;

import com.mycompany.myapp.JhipsterApp;
import com.mycompany.myapp.domain.Advertising;
import com.mycompany.myapp.repository.AdvertisingRepository;
import com.mycompany.myapp.service.AdvertisingService;
import com.mycompany.myapp.service.dto.AdvertisingDTO;
import com.mycompany.myapp.service.mapper.AdvertisingMapper;
import com.mycompany.myapp.web.rest.errors.ExceptionTranslator;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.Validator;

import javax.persistence.EntityManager;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.ZoneOffset;
import java.time.ZoneId;
import java.util.List;

import static com.mycompany.myapp.web.rest.TestUtil.sameInstant;
import static com.mycompany.myapp.web.rest.TestUtil.createFormattingConversionService;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

/**
 * Integration tests for the {@Link AdvertisingResource} REST controller.
 */
@SpringBootTest(classes = JhipsterApp.class)
public class AdvertisingResourceIT {

    private static final String DEFAULT_AD_TYPE = "AAAAAAAAAA";
    private static final String UPDATED_AD_TYPE = "BBBBBBBBBB";

    private static final String DEFAULT_IMG_URL = "AAAAAAAAAA";
    private static final String UPDATED_IMG_URL = "BBBBBBBBBB";

    private static final ZonedDateTime DEFAULT_CREATE_TIME = ZonedDateTime.ofInstant(Instant.ofEpochMilli(0L), ZoneOffset.UTC);
    private static final ZonedDateTime UPDATED_CREATE_TIME = ZonedDateTime.now(ZoneId.systemDefault()).withNano(0);

    @Autowired
    private AdvertisingRepository advertisingRepository;

    @Autowired
    private AdvertisingMapper advertisingMapper;

    @Autowired
    private AdvertisingService advertisingService;

    @Autowired
    private MappingJackson2HttpMessageConverter jacksonMessageConverter;

    @Autowired
    private PageableHandlerMethodArgumentResolver pageableArgumentResolver;

    @Autowired
    private ExceptionTranslator exceptionTranslator;

    @Autowired
    private EntityManager em;

    @Autowired
    private Validator validator;

    private MockMvc restAdvertisingMockMvc;

    private Advertising advertising;

    @BeforeEach
    public void setup() {
        MockitoAnnotations.initMocks(this);
        final AdvertisingResource advertisingResource = new AdvertisingResource(advertisingService);
        this.restAdvertisingMockMvc = MockMvcBuilders.standaloneSetup(advertisingResource)
            .setCustomArgumentResolvers(pageableArgumentResolver)
            .setControllerAdvice(exceptionTranslator)
            .setConversionService(createFormattingConversionService())
            .setMessageConverters(jacksonMessageConverter)
            .setValidator(validator).build();
    }

    /**
     * Create an entity for this test.
     *
     * This is a static method, as tests for other entities might also need it,
     * if they test an entity which requires the current entity.
     */
    public static Advertising createEntity(EntityManager em) {
        Advertising advertising = new Advertising()
            .adType(DEFAULT_AD_TYPE)
            .imgUrl(DEFAULT_IMG_URL)
            .createTime(DEFAULT_CREATE_TIME);
        return advertising;
    }
    /**
     * Create an updated entity for this test.
     *
     * This is a static method, as tests for other entities might also need it,
     * if they test an entity which requires the current entity.
     */
    public static Advertising createUpdatedEntity(EntityManager em) {
        Advertising advertising = new Advertising()
            .adType(UPDATED_AD_TYPE)
            .imgUrl(UPDATED_IMG_URL)
            .createTime(UPDATED_CREATE_TIME);
        return advertising;
    }

    @BeforeEach
    public void initTest() {
        advertising = createEntity(em);
    }

    @Test
    @Transactional
    public void createAdvertising() throws Exception {
        int databaseSizeBeforeCreate = advertisingRepository.findAll().size();

        // Create the Advertising
        AdvertisingDTO advertisingDTO = advertisingMapper.toDto(advertising);
        restAdvertisingMockMvc.perform(post("/api/advertisings")
            .contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(advertisingDTO)))
            .andExpect(status().isCreated());

        // Validate the Advertising in the database
        List<Advertising> advertisingList = advertisingRepository.findAll();
        assertThat(advertisingList).hasSize(databaseSizeBeforeCreate + 1);
        Advertising testAdvertising = advertisingList.get(advertisingList.size() - 1);
        assertThat(testAdvertising.getAdType()).isEqualTo(DEFAULT_AD_TYPE);
        assertThat(testAdvertising.getImgUrl()).isEqualTo(DEFAULT_IMG_URL);
        assertThat(testAdvertising.getCreateTime()).isEqualTo(DEFAULT_CREATE_TIME);
    }

    @Test
    @Transactional
    public void createAdvertisingWithExistingId() throws Exception {
        int databaseSizeBeforeCreate = advertisingRepository.findAll().size();

        // Create the Advertising with an existing ID
        advertising.setId(1L);
        AdvertisingDTO advertisingDTO = advertisingMapper.toDto(advertising);

        // An entity with an existing ID cannot be created, so this API call must fail
        restAdvertisingMockMvc.perform(post("/api/advertisings")
            .contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(advertisingDTO)))
            .andExpect(status().isBadRequest());

        // Validate the Advertising in the database
        List<Advertising> advertisingList = advertisingRepository.findAll();
        assertThat(advertisingList).hasSize(databaseSizeBeforeCreate);
    }


    @Test
    @Transactional
    public void getAllAdvertisings() throws Exception {
        // Initialize the database
        advertisingRepository.saveAndFlush(advertising);

        // Get all the advertisingList
        restAdvertisingMockMvc.perform(get("/api/advertisings?sort=id,desc"))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(jsonPath("$.[*].id").value(hasItem(advertising.getId().intValue())))
            .andExpect(jsonPath("$.[*].adType").value(hasItem(DEFAULT_AD_TYPE.toString())))
            .andExpect(jsonPath("$.[*].imgUrl").value(hasItem(DEFAULT_IMG_URL.toString())))
            .andExpect(jsonPath("$.[*].createTime").value(hasItem(sameInstant(DEFAULT_CREATE_TIME))));
    }
    
    @Test
    @Transactional
    public void getAdvertising() throws Exception {
        // Initialize the database
        advertisingRepository.saveAndFlush(advertising);

        // Get the advertising
        restAdvertisingMockMvc.perform(get("/api/advertisings/{id}", advertising.getId()))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(jsonPath("$.id").value(advertising.getId().intValue()))
            .andExpect(jsonPath("$.adType").value(DEFAULT_AD_TYPE.toString()))
            .andExpect(jsonPath("$.imgUrl").value(DEFAULT_IMG_URL.toString()))
            .andExpect(jsonPath("$.createTime").value(sameInstant(DEFAULT_CREATE_TIME)));
    }

    @Test
    @Transactional
    public void getNonExistingAdvertising() throws Exception {
        // Get the advertising
        restAdvertisingMockMvc.perform(get("/api/advertisings/{id}", Long.MAX_VALUE))
            .andExpect(status().isNotFound());
    }

    @Test
    @Transactional
    public void updateAdvertising() throws Exception {
        // Initialize the database
        advertisingRepository.saveAndFlush(advertising);

        int databaseSizeBeforeUpdate = advertisingRepository.findAll().size();

        // Update the advertising
        Advertising updatedAdvertising = advertisingRepository.findById(advertising.getId()).get();
        // Disconnect from session so that the updates on updatedAdvertising are not directly saved in db
        em.detach(updatedAdvertising);
        updatedAdvertising
            .adType(UPDATED_AD_TYPE)
            .imgUrl(UPDATED_IMG_URL)
            .createTime(UPDATED_CREATE_TIME);
        AdvertisingDTO advertisingDTO = advertisingMapper.toDto(updatedAdvertising);

        restAdvertisingMockMvc.perform(put("/api/advertisings")
            .contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(advertisingDTO)))
            .andExpect(status().isOk());

        // Validate the Advertising in the database
        List<Advertising> advertisingList = advertisingRepository.findAll();
        assertThat(advertisingList).hasSize(databaseSizeBeforeUpdate);
        Advertising testAdvertising = advertisingList.get(advertisingList.size() - 1);
        assertThat(testAdvertising.getAdType()).isEqualTo(UPDATED_AD_TYPE);
        assertThat(testAdvertising.getImgUrl()).isEqualTo(UPDATED_IMG_URL);
        assertThat(testAdvertising.getCreateTime()).isEqualTo(UPDATED_CREATE_TIME);
    }

    @Test
    @Transactional
    public void updateNonExistingAdvertising() throws Exception {
        int databaseSizeBeforeUpdate = advertisingRepository.findAll().size();

        // Create the Advertising
        AdvertisingDTO advertisingDTO = advertisingMapper.toDto(advertising);

        // If the entity doesn't have an ID, it will throw BadRequestAlertException
        restAdvertisingMockMvc.perform(put("/api/advertisings")
            .contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(advertisingDTO)))
            .andExpect(status().isBadRequest());

        // Validate the Advertising in the database
        List<Advertising> advertisingList = advertisingRepository.findAll();
        assertThat(advertisingList).hasSize(databaseSizeBeforeUpdate);
    }

    @Test
    @Transactional
    public void deleteAdvertising() throws Exception {
        // Initialize the database
        advertisingRepository.saveAndFlush(advertising);

        int databaseSizeBeforeDelete = advertisingRepository.findAll().size();

        // Delete the advertising
        restAdvertisingMockMvc.perform(delete("/api/advertisings/{id}", advertising.getId())
            .accept(TestUtil.APPLICATION_JSON_UTF8))
            .andExpect(status().isNoContent());

        // Validate the database contains one less item
        List<Advertising> advertisingList = advertisingRepository.findAll();
        assertThat(advertisingList).hasSize(databaseSizeBeforeDelete - 1);
    }

    @Test
    @Transactional
    public void equalsVerifier() throws Exception {
        TestUtil.equalsVerifier(Advertising.class);
        Advertising advertising1 = new Advertising();
        advertising1.setId(1L);
        Advertising advertising2 = new Advertising();
        advertising2.setId(advertising1.getId());
        assertThat(advertising1).isEqualTo(advertising2);
        advertising2.setId(2L);
        assertThat(advertising1).isNotEqualTo(advertising2);
        advertising1.setId(null);
        assertThat(advertising1).isNotEqualTo(advertising2);
    }

    @Test
    @Transactional
    public void dtoEqualsVerifier() throws Exception {
        TestUtil.equalsVerifier(AdvertisingDTO.class);
        AdvertisingDTO advertisingDTO1 = new AdvertisingDTO();
        advertisingDTO1.setId(1L);
        AdvertisingDTO advertisingDTO2 = new AdvertisingDTO();
        assertThat(advertisingDTO1).isNotEqualTo(advertisingDTO2);
        advertisingDTO2.setId(advertisingDTO1.getId());
        assertThat(advertisingDTO1).isEqualTo(advertisingDTO2);
        advertisingDTO2.setId(2L);
        assertThat(advertisingDTO1).isNotEqualTo(advertisingDTO2);
        advertisingDTO1.setId(null);
        assertThat(advertisingDTO1).isNotEqualTo(advertisingDTO2);
    }

    @Test
    @Transactional
    public void testEntityFromId() {
        assertThat(advertisingMapper.fromId(42L).getId()).isEqualTo(42);
        assertThat(advertisingMapper.fromId(null)).isNull();
    }
}
